﻿using UnityEngine;
using System.Collections;


public class CharacterController : MonoBehaviour
{

    public float maxSpeed;              //maximum character speed
    Animator anim;                      //we need to access animator to modify speed automaticaly

    public AudioClip pickupCoin;
    public AudioClip jumpSound;

    public Transform groundCheck;       //object used for verification of ground
    public float groundRadius;          //how big is our ground sphere
    public float JumpForce;             //the force of our jump on Y axis

    bool DoubleJump = false;
    //bool simpleJump = false;
    public LayerMask whatIsGround;      //what is considered ground ?

    public static bool onGround = false;                //verifies is character is on the ground
    public static bool isStuck = false;
    public static bool isDead = false;
    public static bool closeToFinish = false;

    public static bool canMove = false;            //whether to move or not (also influences the time.timeScale, alternating it between 1 and 0
    public static bool stopCameraMark = false;




    //private bool canMove = false;
    private float timeBetweenJumps = 0.0f;
    private float curPos = 0.0f;
    private float lastPos = 0.0f;



    private int maxObtainableScore; // maximum amount of score that can be obtained in the current level



    void Awake()
    {
        anim = GetComponent<Animator>();
    }

    // Use this for initialization
    void Start()
    {

        stopCameraMark = false;


        closeToFinish = false;
        isStuck = false;
        isDead = false;
        HelperScript.score = 0;

        HelperScript.levelName = Application.loadedLevelName;

        maxObtainableScore = PlayerPrefs.GetInt(HelperScript.levelName + "_Arguments", 0); //we stored the max obtainable score in player pref for every level
        groundRadius = 0.3f;
        canMove = false;
        //AdmobVNTIS_Interstitial x = AdmobVNTIS_Interstitial._get();

    }



    //used for animator sync; no need for time.deltatime
    //does not fluctuate; better for physics stuff
    void FixedUpdate()
    {




        //We check every time to see if the character hit what is considered ground or not
        //If true -> character is on permitable ground

        if ((Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround)))
        {
            onGround = true;
        }
        else
        {
            onGround = false;
        }

        //animator needs to know if the character is on the ground
        anim.SetBool("Ground", onGround);

        //how high are we jumping. the speed on Y axis
        anim.SetFloat("VerticalSpeed", GetComponent<Rigidbody2D>().velocity.y);

        if (onGround) { DoubleJump = false; }
        if (!onGround)
        {
            return;
        }
        //get movement axis
        float move = Input.GetAxis("Horizontal");

        //gives the speed the value of our movement
        //speed cannot be negative in this case as fliping is 
        //done using Flip(), so we use absolute value for it
        //this is used for changing between IDLE-MOVE status if they exist
        anim.SetFloat("Speed", Mathf.Abs(move));




    }



    //input dependent actions should be put here for better precision
    void Update()
    {

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Application.LoadLevel("LevelSelectScene");
        }

        //freeze screen when starting the game and wait for tap to start
        if (canMove)
        {
            Time.timeScale = 1f;
        }
        if (!canMove)
        {
            Time.timeScale = 0f;
        }

        //reload level on death
        if (isDead)
        {
            maxSpeed = 0f;
            isStuck = true;
            Application.LoadLevel(Application.loadedLevelName);
        }


        curPos = transform.position.x;
        if (curPos == lastPos)
        {
            isStuck = true;
        }
        else if (curPos > lastPos)
        {
            isStuck = false;
        }
        lastPos = curPos;


        if (onGround || DoubleJump)
        {

            timeBetweenJumps = 0.0f;
        }
        else if (!DoubleJump)
        {
            timeBetweenJumps += Time.deltaTime;
        }




        //move character on X axis, Y remains the same
        GetComponent<Rigidbody2D>().velocity = new Vector2(maxSpeed, GetComponent<Rigidbody2D>().velocity.y);

        //if we have pressed Space or Tap on mobile, we are not grounded anymore
        //and we need to jump with a certain Force
        if ((onGround || !DoubleJump) && (((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)) || Input.GetKeyDown(KeyCode.Space)))
        {

            //canMove = true;
            //make simple jump
            if (onGround && !DoubleJump && Time.timeScale > 0f)
            {

                anim.SetBool("Ground", false);
                //we can execute the jump in different modes

                GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, 0);
                GetComponent<Rigidbody2D>().AddForce(new Vector2(0, JumpForce));
                //audio.PlayOneShot(jumpSound, 0.5f);
            }
            //has made single jump, make double jump only if the second tap was fast enough, meaning less than 5s away from the first one
            else if (!onGround && !DoubleJump && timeBetweenJumps < 5f && Time.timeScale > 0f)
            {

                anim.SetBool("Ground", false);
                //we can execute the jump in different modes
                GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, 0);
                GetComponent<Rigidbody2D>().AddForce(new Vector2(0, JumpForce));
                DoubleJump = true;
                //audio.PlayOneShot(jumpSound, 0.5f);

            }

        }



    }


    void OnTriggerEnter2D(Collider2D coll)

    {
        if (coll.tag == "killerObject")
        {

            if (isDead == false)
            {

                //GoogleAdsManager.Instance.setDieCount(GoogleAdsManager.Instance.getDieCount() + 1);

                //if (GoogleAdsManager.Instance.getDieCount() >= GoogleAdsManager.Instance.showAfterDie)
                //{

                //    GoogleAdsManager.Instance.RequestInterstitial();
                //    GoogleAdsManager.Instance.setDieCount(0);

                //}

            }

            isDead = true;
        }
        else if (coll.tag == "Coin")
        {


            HelperScript.score += 100;
            Destroy(coll.gameObject);
            //int rnd = Random.Range(1,8);
            GameObject coinParticles = (GameObject)Instantiate(Resources.Load("CST-PSG-1"));
            coinParticles.transform.position = new Vector2(coll.gameObject.transform.position.x, coll.gameObject.transform.position.y);

            coinParticles.GetComponent<ParticleSystem>().Play();
            //coinParticles.particleEmitter.emit = true;


            Destroy(coinParticles, 0.8f);
            GetComponent<AudioSource>().PlayOneShot(pickupCoin, 0.35f);
        }
        //if character hit the invisible colider with the tag closeToFinishMark, StartAppInterstitialShow.cs will load a StartApp interstitial Ad
        else if (coll.tag == "closeToFinishMark")
        {
            closeToFinish = true;
            //	AdmobVNTIS_Interstitial._showInterstitialImmediately ();
        }
        else if (coll.tag == "stopCameraMark")
        {
            stopCameraMark = true;
            //AdmobVNTIS_Interstitial._showInterstitialImmediately ();
        }
        //the character has completed a level
        else if (coll.tag == "levelFinished")
        {
            //if the player has played this level before and has earned stars for it, get the number from PlayerPrefs
            int currentStarNumber = PlayerPrefs.GetInt(HelperScript.levelName + "StarCount", 0);

            //score is between -1 and 70% of maximum score - give one star
            if (((HelperScript.score > -1) && (HelperScript.score < ((0.7) * maxObtainableScore))) && currentStarNumber < 1)
            {

                //give 1 star
                PlayerPrefs.SetInt(HelperScript.levelName + "StarCount", 1);
                UnlockNextLevel();
            }
            //score is between 70% and 90% of maximum score - give two stars
            else if (((HelperScript.score > ((0.7) * maxObtainableScore)) && (HelperScript.score < ((0.9) * maxObtainableScore))) && currentStarNumber < 2)
            {

                PlayerPrefs.SetInt(HelperScript.levelName + "StarCount", 2);
                UnlockNextLevel();
            }
            //score is between 90% and 100% of maximum score - give three stars
            else if ((HelperScript.score > ((0.9) * maxObtainableScore)) && currentStarNumber < 3)
            {
                PlayerPrefs.SetInt(HelperScript.levelName + "StarCount", 3);
                UnlockNextLevel();
            }

            LoadNextLevel();

        }


    }

    private void LoadNextLevel()
    {

        //if this is the final level
        if (PlayerPrefs.GetString("LastLevelName", null) == HelperScript.levelName)
        {
            //load level select scene
            Application.LoadLevel("LevelSelectScene");
            //GoogleAdsManager.Instance.RequestInterstitial();

            //GoogleAdsManager.Instance.setDieCount(0);

        }
        //if this is not the final level
        else
        {
            //increment the current level number, to load the next one
            HelperScript.currentLevelNumber++;
            //load the next level
            Application.LoadLevel("Level" + (HelperScript.currentLevelNumber).ToString());
            //GoogleAdsManager.Instance.RequestInterstitial();
            //GoogleAdsManager.Instance.setDieCount(0);
        }

    }



    private void UnlockNextLevel()
    {
        //if this is not the final level
        if (!(PlayerPrefs.GetString("LastLevelName", null) == HelperScript.levelName))
        {
            //unlock the next level
            PlayerPrefs.SetString("Level" + (HelperScript.currentLevelNumber + 1).ToString(), "unlocked");
        }

    }



}
